/** @brief CFAST焊接单元
 * 
 * @version  0.1
 * @author   yangqiuyou
 * @date     2024.12.27
 *         _
 *     ___| |__   ___ _ __   __ _  ___  _ __   __ _
 *    / __| '_ \ / _ \ '_ \ / _` |/ _ \| '_ \ / _` |
 *    \__ \ | | |  __/ | | | (_| | (_) | | | | (_| |
 *    |___/_| |_|\___|_| |_|\__, |\___/|_| |_|\__, |
 *                          |___/             |___/
 * @copyright (c) 2025 by 神工仿真, All Rights Reserved.
 */
#pragma once

#include "Utility/Algebra/Point.h"
#include "DataStructure/Common/Id.h"
#include "DataStructure/Input/Material/IsotropicMaterial.h"
#include "DataStructure/Input/Element/CFASTData.h"
#include "DataStructure/Input/Property/PFASTData.h"

#include "SGFem/ElementCalculator/Interface/IElementCalculator.h"
#include "../Common/ConnectElementExport.h"

SG_FEMSOLVER_ELEMENT_NAMESPACE_OPEN

class ConnectElement_DECLSPEC CfastCalculator : public SG::FEMSolver::Element::IElementCalculator
{
  public:
    CfastCalculator ();
    virtual ~CfastCalculator () = default;

    /** @brief 计算 CFAST 投影点之间单元刚度矩阵
     *
     * @param L           单元长度
     * @param property    截面属性
     * @param[out] kl     单元刚度矩阵
     * @author   yangqiuyou
     * @date     2025.04.09
     */
    void ComputeStiffness (const SG::DataStructure::Common::Real&           L,
                           const SG::DataStructure::FEM::PFASTData&         property,
                           _OUT  SG::Algebra::Matrixd&                      kl);

    /** @brief    计算辅助点和连接节点之间RBE3权系数 (三角形)
     * 
     * @param    x                  投影点局部坐标下 x, y
     * @param    y                 
     * @param    connectLocCoord    连接单元节点在单元局部坐标下的坐标值
     * @param    weights            权系数
     * @author   wanghuan
     * @date     2025.04.13
     */
    static void ComputeTriWeights (const SG::DataStructure::Common::Real&             x,
                                   const SG::DataStructure::Common::Real&             y,
                                   const SG::Algebra::Matrixd&                        connectLocCoord,
                                   std::vector<SG::DataStructure::Common::Real>& _OUT weights);

    /** @brief    计算辅助点和连接节点之间RBE3权系数 (四边形)
     * 
     * @param    x                  投影点局部坐标下 x, y
     * @param    y                 
     * @param    connectLocCoord    连接单元节点在单元局部坐标下的坐标值
     * @param    weights            权系数
     * @author   wanghuan
     * @date     2025.04.13
     */
    static void ComputeQuadWeights (const SG::DataStructure::Common::Real&             x,
                                    const SG::DataStructure::Common::Real&             y,
                                    const SG::Algebra::Matrixd&                        connectLocCoord,
                                    std::vector<SG::DataStructure::Common::Real>& _OUT weights);

    /** @brief 获取辅助点的在壳单元坐标系下的局部坐标
     *
     * @param pLocal             投影点局部坐标
     * @param Tshell             壳转换矩阵
     * @param T                  粱转换矩阵
     * @param a                  水平长度
     * @param[out] auxLocalCoord    辅助点局部Matrix类型
     * @author   yangqiuyou
     * @date     2025.04.09
     */
    static void ComputeAuxNode (const SG::Algebra::Point&         pLocal,
                         const SG::Algebra::Matrix&               Tshell,
                         const SG::Algebra::Matrix&               T,
                         const SG::DataStructure::Common::Real&   a,
                         _OUT SG::Algebra::Matrix&                auxLocalCoord);

    virtual void Initialize (SG::DataStructure::FEM::ElementTypes type) override;
    virtual void ComputeElementMatries (const SG::DBManager::DBServiceFactorySP dbServiceFactory) override;
    virtual void DataRecovery (const SG::DBManager::DBServiceFactorySP             dbServiceFactory,
                               int                                                 subcaseId,
                               SG::DataStructure::Common::Real time,
                               const std::vector<SG::DataStructure::Common::Real>& globalDisplacement) override;
    virtual void ComputeStressStiffness (const SG::DBManager::DBServiceFactorySP dbServiceFactory, int staticSubId) override;

    static ElementCalculatorSP Create ()
    {
        return std::make_shared<CfastCalculator> ();
    }

     /**
     * @brief 计算CFAST单元内力
     * 
     * @param [out] elementInternalForce CFAST单元内力
     * @author   yangqiuyou
     * @date     2025.09.16
     */
    static void ComputeElementInternalForce(const SG::DBManager::DBServiceFactorySP             dbServiceFactory,
                                            const std::vector<SG::DataStructure::Common::Real>& globalDisplacement,
                                            _OUT SG::Algebra::Matrixd&                          elementInternalForce
    );
  private:
};
SG_FEMSOLVER_ELEMENT_NAMESPACE_CLOSE